package com.niit.scala

object Base_07 {


  def main(args: Array[String]): Unit = {
    /*
      函数式编程 ：方法的参数列表可以接收函数对象
     */
    //foreach
    var list1 = List(1,2,3,4,5,6,7)
    //目的： 用foreach遍历list1 i:Int：列表中的每一个元素
    //初级版 完整版
    list1.foreach(  (i:Int) => print(i)    )
    //升级版 省略了参数的数据类型
    list1.foreach( i =>  print(i) )
    println("--------究极版---------")
    //究极版：_表示列表中的每一个元素
    list1.foreach( print(_) )

    //map: 集合的映射操作 是将一种数据类型转换为另一种数据类型过程
    //需求：某电影网站，需要观众对电影进行打分。 等级 1 2 3 4 5. 但是观众只能通过 * 进行打分
    var list2 = List(1,2,3,4)
    //初级版 i:Int 就是列表中的每个元素
    var ll1 = list2.map( (i:Int) => "*" * i  )
    print(ll1)
    //升级版 省略了参数的数据类型 Scala带有类型推断的功能
    var ll2 = list2.map(i => "*" * i)
    println(ll2)
    //究极版:_表示列表中的每一个元素
    var ll3 = list2.map("*" * _)
    println(ll3)

    //flatMap : flatten:扁平化（将列表中所有子列表中的元素，都合并到一个新的列表）
    /*
     map:将列表中的每一个元素都变成一个新的元素
     */
    var list3 = List("hadoop hive spark flume","hbase java python java")
    //  _:"hadoop hive spark flume"
    val ll4: List[Array[String]] = list3.map(_.split(" "))
    // 最终效果 List("hadoop","hive","spark","flume","hbase","java","python","java")
    //方式一          // _ : "hadoop hive spark flume"
                     // _ :"hbase java python java"
                    // ll4 = List( Array(hadoop,hive,spark,flume),Array(hbase,java,python,java) )
    println(ll4.size)
    ll4.foreach( arr => arr.foreach( println(_)) )
    var ll5 = ll4.flatten
    println(ll5)
    //方式二
    var ll6 = list3.flatMap(_.split(" "))
    println(ll6)

    //filter:过滤除符合一定条件(true/false)的数据
    // 1 to 9 生成一个数组， 数组转换 List
    var list4 = (1 to 9).toList
    //将list4 过滤除能够被2整除的数据
    val ls1: List[Int] = list4.filter(_ % 2 == 0)
    println(ls1)

    /*
      排序：
          sorted：对集合元素进行默认排序
          sortBy: 对集合按照指定字段排序
          sortWith: 对集合进行自定义排序
     */
    //sorted：默认排序
    val list5 = List(3,1,2,5,7,4,8,9)
    var ls2 = list5.sorted; //将排序后的数据返回一个新的列表
    println(ls2)
    println(ls2.reverse)//集合反转
    //sortBy:对集合按照指定字段进行排序
    val list6 = List("01 hadoop","02 spark","03 java","04 python")
    //需求：按照字母顺序进行排序
                  //  每个元素的 单词
    var ls3 = list6.sortBy(  _.split(" ")(1)  )
    println(ls3)
    //sortwith：对集合进行自定义排序
    val list7 = List(3,1,2,5,7,4,8,9)
    //将list7 进行降序排序
    /*  冒泡排序算法
        x=3   y=1  3 > 1
        x =3  y=2 3 > 2
        x = 3  y =5  3 > 5   5  3 1 2
        x= 3   y=7
     */
    val ls4 = list7.sortWith((x, y) => x > y)
    println(ls4)
    //究极版 此时 x和y 都是表示列表中的每一个元素，并且x和y也是固定的位置。所以可以直接用_来表示了
    //第一个_ :x  第二个_：y
    val ls5 =  list7.sortWith(_ > _)
    println(ls5)

    /*
    分组: 将数组/集合按照指定条件进行分组 groupBy
     需求： 1. 将一个班的学生按照性别进行分组
           2. 统计不同性别的人数
     */
    var list8 = List( ("张三","男"), ("李四","女") , ("王五","男") )
    println(list8)
                                                //第一个_:  ("张三","男")
                                                // _2 : 男
    val ls6: Map[String, List[(String, String)]] = list8.groupBy(_._2)
    println(ls6) //HashMap(男 -> List((张三,男), (王五,男)), 女 -> List((李四,女)))
    // Map(    ("张三",13),("李四",24)       )
    /*   ls6 == Map   (   (男，List((张三,男), (王五,男))) ,  (女, List((李四,女)))  )
                                    1                                 2
       Map
          key(String): 男    value( List( 元组 ))   List((张三,男), (王五,男))
                                   List的长度就是 人数
          key(String): 女    value(List( 元组 ))    List((李四,女))
     */
                      // x1:   (  男， List((张三,男), (王五,男))     )
                      // x2:   (  女,    List((李四,女))   )
          //元组取值用的是序号(1) 列表 数组 集取值用的是索引值(0) 字典取值用的key
          //x不能写成_,因为使用了两次_,并且都是同一个含义
    val res: Map[String, Int] = ls6.map(x=> (x._1,x._2.size)  )
    //                                      (男，2)
    //                                      (女,1)
    println(res)

    /*
     聚合操作：将一个列表中的数据合并为一个
        reduce:用来对集合元素进行聚合计算
        fold: 用来对集合元素进行折叠计算
     */
    //reduce
    val list9 = (1 to 10).toList
    val i1: Int = list9.reduce((x, y) => x + y)
    println(i1)
    val i2: Int = list9.reduce(_ + _)

    /*
      fold折叠计算：和reduce一样，但是多了一个初始值参数
     */
    //需求：定义一个列表1-10，假设初始值为100，使用fold方法计算所有元素的和
    // 100 + 1 + 2 + 3 +………………+10
    val i3: Int = list9.fold(100)(_ + _)
    println(i3)
  }




}
